package Avocado.util {

	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Rectangle;

	public class StartDragPerspective {
		
		private var target:DisplayObject;
		private var dragRect:Rectangle;
		
		private var startMouseX:Number;
		private var startMouseY:Number;
		
		private var originalX:Number;
		private var originalY:Number;

		private var objectX:Number;
		private var objectY:Number;

		public function StartDragPerspective(_target:DisplayObject, _dragRect:Rectangle=null){
			target = _target;
			dragRect = _dragRect;
			
			if (target.stage){
				addDrag();
			} else {
				waitingForStage();
			}
		}

		public static function drag(_target:DisplayObject, _dragRect:Rectangle):StartDragPerspective{
			return new StartDragPerspective(_target, _dragRect);
		}

		private function waitingForStage():void{
			target.addEventListener(Event.ADDED_TO_STAGE, targetHasStage);
			function targetHasStage(e:Event):void{
				target.removeEventListener(Event.ADDED_TO_STAGE, targetHasStage);
				addDrag();	
			}
		}
		
		private function addDrag():void{
			originalX = target.x;
			originalY = target.y;

			target.addEventListener(MouseEvent.MOUSE_DOWN, mouseDown);
			target.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
		}

		
		private function updateTarget(e:Event):void{
			target.x = objectX + (target.stage.mouseX - startMouseX);
			target.y = objectY + (target.stage.mouseY - startMouseY);
			
			if (dragRect){
				if (target.x > (originalX + dragRect.width)){
					target.x = (originalX + dragRect.width);
				} else if (target.x < originalX) {
					target.x = originalX;
				}

				if (target.y > (originalY + dragRect.height)){
					target.y = (originalY + dragRect.height);
				} else if (target.y < originalY) {
					target.y = originalY;
				}
			}
		}

		private function mouseDown(e:MouseEvent):void{
			target.stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
			
			startMouseX = target.stage.mouseX;
			startMouseY = target.stage.mouseY;
			
			objectX = target.x;
			objectY = target.y;

			target.addEventListener(Event.ENTER_FRAME, updateTarget);
		}
		
		private function mouseUp(e:MouseEvent):void{
			target.stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
			target.removeEventListener(Event.ENTER_FRAME, updateTarget);
		}


	}
}